#!/usr/bin/python
"""
    File:       ServiceControl.py
    Brief:      Manager service process and instance
    Author:     Xu Qiang
    Version:    1.0
    Date:       2017 - 4 - 18  
"""


import os
import psutil
import subprocess
import Static


class ServiceState( object ):
    Active = "active"
    Killed = "killed"
    Freezing = "Freezing"


def isProcessExist( processName ):
    for p in psutil.process_iter():
        if p.name == processName:
            return True

    return False


def killProcessTreeWithName( processName ):
    for p in psutil.process_iter():
        try:
            if p.name == processName:
                for child in p.get_children( recursive = True ):
                    try:
                        child.kill()
                    except:
                        pass
                p.kill()
        except Exception, e:
            from Log import LogW
            LogW.write( "killProcessTreeWithName cause exception %s" % str( e ) )


def killProcessWithName( processName ):
    for p in psutil.process_iter():
        try:
            if p.name == processName:
                p.kill()
        except Exception, e:
            from Log import LogW
            LogW.write( "killProcessWithName cause exception %s" % str( e ) )


class IService( object ):
    def start( self ):
        '''
        return True if start successfully, else return False, never raise;
        '''
        pass
    def stop( self ):
        '''
        should always work, and never raise
        '''
        pass
    def restart( self ):
        '''
        return True if start successfully, else return False, never raise;
        '''
        pass
    @property
    def state( self ):
        '''
        return ServiceState.Active when service is active, else return ServiceState.Killed
        '''
        pass

class ServicePool( object ):
    def __init__( self ):
        self._pool = {}

#     def __del__( self ):
#         self.stop()

    def add( self, name, iServerPtr ):
        self.remove( name )
        self._pool[name] = iServerPtr

    def remove( self, name ):
        if self._pool.has_key( name ):
            self._pool[name].stop()
            self._pool.pop( name , None )

    def get( self, name = "ALL" ):
        if name == "ALL":
            result = []
            for key in self._pool.keys():
                result.append( self._pool[key] )
            return result
        elif self._pool.has_key( name ):
            return self._pool.get( name )
        else:
            return None

    def start( self, name = "ALL" ):
        if name == "ALL":
            for key in self._pool.keys():
                self._pool[key].start()
        elif self._pool.has_key( name ):
            return self._pool.get( name ).start()
        else:
            return None

    def stop( self, name = "ALL" ):
        if name == "ALL":
            for key in self._pool.keys():
                self._pool[key].stop()
        elif self._pool.has_key( name ):
            return self._pool.get( name ).stop()
        else:
            return None

    def restart( self, name = "ALL" ):
        if name == "ALL":
            for key in self._pool.keys():
                self._pool[key].restart()
        elif self._pool.has_key( name ):
            return self._pool.get( name ).restart()
        else:
            return None

    def __getattr__( self, attr ):
        if attr.upper() == "ALL":
            return self.get()
        elif self._pool.has_key( attr ):
            return self._pool.get( attr )
        else:
            raise AttributeError( attr )


_servicePool = None
_serviceWatcherProcess = None

def initializeService():
    global _servicePool
    if _servicePool != None:
        _servicePool.stop( "ALL" )
        _servicePool = None
    _servicePool = ServicePool()


def finitializeService():
    global _servicePool
    if _servicePool != None:
        _servicePool.stop( "ALL" )
        _servicePool = None

def _initializeService():
    global _servicePool
    _servicePool = ServicePool()

def _finitializeService():

    global _servicePool
    if isinstance( _servicePool, ServicePool ):
        _servicePool.stop( "All" )
        _servicePool = None
    else:
        _servicePool = None

def addService( name ):
    name = name.strip().lower()
    global _servicePool

    if name == "browser":
        from Browser  Driver import BrowserDriver as Browser
        _servicePool.add( "browser", Browser( Static.installEnvConf.BrowserType ) )
        return True
    else:
        #toDo:   Extend Service
        pass
    return False


def startService( name ):
    name = name.strip().lower()
    global _servicePool

    if _servicePool.get( name ) == None:
        if not addService( name ):
            return False

    if name == "browser":
        return _servicePool.start( "browser" )
    else:
        #toDo: Extend Service
        return False


def stopService( name ):
    name = name.strip().lower()
    global _servicePool
    if _servicePool == None:
        return

    elif name == "browser":
        _servicePool.stop( "browser" )
    else:
        #toDo: Extend Service
        pass


def restartService( name ):
    name = name.strip().lower()
    stopService( name )
    import time
    time.sleep( 1 )
    return startService( name )


def getService( name ):
    '''
    may return None, also may return a killed service
    '''
    name = name.strip().lower()
    global _servicePool
    if _servicePool == None:
        from Log import LogW
        LogW.write( "getService(%s) return None because service pool is not initialized yet" % name )
        return None
    result = _servicePool.get( name )
    if result == None:
        addService( name )
        startService( name )
        result = _servicePool.get( name )

    if result == None or result.state != ServiceState.Active:
        from Log import LogW
        LogW.write( "getService(%s) return inactive service." % name )

    return result


def startAllServices():
    initializeService()
    addService( "Browser" )
    stopService( "Browser" )
    startService( "Browser" )

def stopAllServices():
    stopService( "Browser" )
    finitializeService()

